﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;


namespace RStudio.UIFramwork.Editor
{
    /// <summary>
    /// 自动根据UI生成脚本
    /// </summary>
    /// <remarks>
    /// <br/> [1] 名字以 "!" 开头的 GameObject 会被忽略
    /// <br/> [2] 名字包含 "~" 的 GameObject 及其子对象会被忽略
    /// </remarks>
    public class UITemplateTool : UnityEditor.Editor
    {
        const string SPACE = "\t";

        static string m_UIDetailTemplate;
        static string m_UITemplate;
        public static UIFramworkSetting Setting;
        public static List<ComponentDetail> Details;

        #region Unity 菜单
        [MenuItem("RStudio/UI Framwork/一键资产化生成/常规", false, 1)]
        [MenuItem("Assets/UI Framwork/一键资产化生成/常规", false, 1)]
        private static void CreateUIPage()
        {
            GameObject target = UnityEditor.Selection.activeGameObject;
            
            // 检验对象有效性
            bool isOk = TemplateUtil.Valied<RectTransform>(target);
            if (!isOk) return;

            LoadEnvironment();
            if (!Setting) return; // 若设置丢失，终止流程

            TemplateUtil.DoCreatePrefab(target, Setting.PathUIPrefab);
            DoCreateUIBase(target.name);
            DoCreateDetail(target);

            // 生成后刷新资源库，确保脚本立即显示
            AssetDatabase.Refresh();
            EditorUtility.DisplayDialog("提示", $"脚本生成完成！\nDetail脚本路径：Assets/{Setting.PathUIDetail}\nBase脚本路径：Assets/{Setting.PathUIBase}", "确认");
        }

        [MenuItem("RStudio/UI Framwork/仅更新 Detail/常规", false, 2)]
        [MenuItem("Assets/UI Framwork/仅更新 Detail/常规", false, 2)]
        private static void UpdateDetail()
        {
            LoadEnvironment();
            if (!Setting) return;

            // 1. 识别对象有效性
            GameObject target = Selection.activeGameObject;
            if (!TemplateUtil.Valied<RectTransform>(target)) return;

            // 2. 仅更新
            DoCreateDetail(target);

            EditorUtility.DisplayDialog("提示", $"Detail脚本更新完成！\n路径：Assets/{Setting.PathUIDetail}", "确认");
        }


        [MenuItem("RStudio/UI Framwork/一键资产化生成/实验性", false, 1)]
        [MenuItem("Assets/UI Framwork/一键资产化生成/实验性", false, 1)]
        private static void CreateUIPageExp()
        {
            GameObject target = UnityEditor.Selection.activeGameObject;

            // 检验对象有效性
            bool isOk = TemplateUtil.Valied<RectTransform>(target);
            if (!isOk) return;

            LoadEnvironment();
            if (!Setting) return; // 若设置丢失，终止流程

            TemplateUtil.DoCreatePrefab(target, Setting.PathUIPrefab);
            DoCreateDetail(target, true);
            DoCreateUIBase(target.name);

            AssetDatabase.Refresh();
            EditorUtility.DisplayDialog("提示", $"脚本生成完成！\nDetail脚本路径：Assets/{Setting.PathUIDetail}\nBase脚本路径：Assets/{Setting.PathUIBase}", "确认");
        }

        [MenuItem("RStudio/UI Framwork/仅更新 Detail/实验性", false, 2)]
        [MenuItem("Assets/UI Framwork/仅更新 Detail/实验性", false, 2)]
        private static void UpdateDetailExp()
        {
            LoadEnvironment();
            if (!Setting) return;

            // 1. 识别对象有效性
            GameObject target = Selection.activeGameObject;
            if (!TemplateUtil.Valied<RectTransform>(target)) return;

            // 2. 仅更新
      
            DoCreateDetail(target, true);

            EditorUtility.DisplayDialog("提示", $"Detail脚本更新完成！\n路径：Assets/{Setting.PathUIDetail}", "确认");
        }

        #endregion



        /// <summary>
        /// 创建|组件详细
        /// </summary>
        public static void DoCreateDetail(GameObject target, bool useExp = false)
        {
            // 移除错误命名
            string targetName = target.name.Replace(" ", "_");
            target.name = targetName;

            // 清除缓存
            // 捕获组件数据
            // 生成UIBase
            // 生成UIDetail
            Details.Clear();

            if (useExp)
            { 
                TemplateUtil.DoCollectComponentsExp(target.transform, string.Empty, Details);
            }
            else
            {
                TemplateUtil.DoCollectComponents(target.transform, string.Empty, Details);
            }    

            // 创建工具路径（若不存在）
            UnitFileUtil.CreateFolder($"{Application.dataPath}/{Setting.PathUIUtil}/{targetName}");
            // 仅更新 Detail
            DoCreateUIDetail(targetName);
            Details.Clear();

            AssetDatabase.Refresh();
        }

        /// <summary>
        /// 创建|UIBase
        /// </summary>
        public static void DoCreateUIBase(string name)
        {
            // 构建基础脚本内容（添加类注释 + 规范缩进）
            string mono = string.Copy(m_UITemplate);
            mono = mono.Replace("#ClassName#", name)
                       .Replace("#DetailName#", $"Detail{name}");
            // 
            string baseSavePath = $"{Application.dataPath}/{Setting.PathUIBase}/{name}.cs";
            UnitFileUtil.Save(baseSavePath, mono);
        }
        
        /// <summary>
        /// 创建|UIDetail
        /// </summary>
        public static void DoCreateUIDetail(string name)
        {
            var newList = Details
                .GroupBy(detail => detail.NodePath)
                .OrderBy(group => group.Key)
                .SelectMany(group => group.OrderBy(detail => detail.Component.GetType().Name));

            // 建立字段规则 + 索引规则
            StringBuilder property = new StringBuilder();
            StringBuilder indexDet = new StringBuilder();

            foreach (var item in newList)
            {
                indexDet.AppendLine(
                    string.IsNullOrEmpty(item.NodePath)
                    ? $"{SPACE}{SPACE}{item.Name} = transform.GetComponent<{item.Component.GetType().Name}>();"
                    : $"{SPACE}{SPACE}{item.Name} = transform.Find(\"{item.NodePath}\").GetComponent<{item.Component.GetType().Name}>();");

                property.AppendLine($"{SPACE}public {item.Component.GetType().Name} {item.Name};");
            }


            // 替换模板并保存脚本（添加空行分隔逻辑块）
            string detail = string.Copy(m_UIDetailTemplate);
            detail = detail
                .Replace("#ClassName#", $"Detail{name}")
                .Replace("#Property#", $"{property.ToString().TrimEnd('\n')}")
                .Replace("#Component#", $"{indexDet}");

            string detailSavePath = $"{Application.dataPath}/{Setting.PathUIDetail}/Detail{name}.cs";
            UnitFileUtil.Save(detailSavePath, detail);
        }

        /// <summary>
        /// 加载 | 环境配置（模板、路径设置）
        /// </summary>
        public static void LoadEnvironment()
        {
            // 加载配置文件
            Setting = UnitFileUtil.GetFile<UIFramworkSetting>("设置");

            Details ??= new List<ComponentDetail>();

            if (!Setting)
            {
                UnityEngine.Debug.LogError("【UITools】UIFramworkSetting配置文件丢失，请检查！");
                return;
            }

            // 校验并创建必要路径（避免路径不存在导致保存失败）
            UnitFileUtil.CreateFolder($"{Application.dataPath}/{Setting.PathUIBase}");
            UnitFileUtil.CreateFolder($"{Application.dataPath}/{Setting.PathUIDetail}");
            UnitFileUtil.CreateFolder($"{Application.dataPath}/{Setting.PathUIUtil}");
            UnitFileUtil.CreateFolder($"{Application.dataPath}/{Setting.PathUIPrefab}");

            // 加载脚本模板（若模板丢失，提示错误）
            try
            {
                m_UIDetailTemplate = System.IO.File.ReadAllText(UnitFileUtil.GetPath("UI Detail Template"));
                m_UITemplate = System.IO.File.ReadAllText(UnitFileUtil.GetPath("UI Template"));
            }
            catch (Exception e)
            {
                UnityEngine.Debug.LogError($"【UITools】加载脚本模板失败：{e.Message}");
                EditorUtility.DisplayDialog("错误", $"加载脚本模板失败：{e.Message}\n请检查模板文件是否存在", "了解");
            }
        }
    }
}